<template>
  <div>
    <p>
      <input type="text" v-model="msg" />
    </p>
    <hr />

    <p>
      <input type="text" v-model.number="x" />
      <input type="text" v-model.number="y" />
    </p>

    <hr />
    <p @click="userinfo.age++">{{ userinfo.name }}--{{ userinfo.age }}</p>
    <p @click="userinfo.son.age++">
      {{ userinfo.son.username }}--{{ userinfo.son.age }}
    </p>

    <hr />

    <p @click="girlStar.age++">{{ girlStar.name }}--{{ girlStar.age }}</p>

    <hr />

    <p id="num" @click="num++">num:{{ num }}</p>
  </div>
</template>

<script setup>
import { reactive, ref, watch, watchEffect } from "vue";
const msg = ref("北京北京");
// 创建一个侦听器, 侦听响应式状态的变化
// 语法1: watch(要监听的数据, 回调函数callback)
watch(msg, (newvalue, oldvalue) => {
  // newvalue 新值
  // oldvalue 旧值
  // console.log(newvalue, oldvalue);
});

// 语法2: watch (箭头函数,回调函数)
// 该处箭头函数就是getter 函数, 也就是计算属性, 当该计算属性依赖的值 x或y 发生改变,
// 则计算属性发生改变, 进而监听器watch的回调函数触发, 实现数据的监听
const x = ref(0);
const y = ref(0);

// watch(
//   () => x.value + y.value,
//   (sum) => {
//     console.log("sum", sum);
//   }
// );

// 语法3: watch ([监听的数据1,监听数据2,....],()=>{触发回调函数})
// 当数组中的任意一个值发生改变, 就会触发watch 的回调函数
watch([x, y], (newval, oldval) => {
  console.log(newval, oldval);
});

// 语法4: 深层监听器
// 在组合式api 中 watch 默认深层监听器, 不需要再设置deep:true,设置深层监听deep:true 也行
// 立即监听 immediate: true
const userinfo = reactive({
  name: "谢贤",
  age: 70,
  son: {
    username: "谢霆锋",
    age: 45,
  },
});

watch(
  userinfo,
  (newvalue, oldvalue) => {
    console.log(newvalue, oldvalue);
  },
  { deep: true, immediate: true }
);

// 语法5: watchEffect
// 语法: watchEffect(()=>{ })
// 注意: 当回调函数中写什么值, 则就监听什么值,特别的智能
// 特点: 01:不需要写监听的源数据, 02:立即会监听. 03:回调函数中有什么值就监听什么值
// 可以在回调函数中写多个监听的数据, 这样就实现了多数据的监听
const girlStar = ref({
  name: "任素汐",
  age: 30,
});

watchEffect(() => {
  console.log(girlStar.value.age);
  console.log(msg.value);
});

// 语法6:  watch 侦听器的执行时机
// 定义: watch 侦听器的执行时机是在vue 组件更新前执行, 所有在侦听器中获取的dom 为更新前的dom
const num = ref(10000);
watchEffect(
  () => {
    console.log(num.value);
    console.log(document.querySelector("#num").innerHTML);
  },
  {
    flush: "post",
  }
);

// watch(
//   num,
//   () => {
//     console.log(num.value);
//     console.log(document.querySelector("#num").innerHTML);
//   },
//   {
//     flush: "post",
//   }
// );
</script>
<style scoped>
</style>